using System;
using System.Reflection;

namespace Framework.DataTable
{
    public delegate object DataParseMethod(string value);
    public class DataParserConfig
    {
        public string Name { get; private set; }
        public string ParseScript { get; private set; }
        public string EncodeScript { get; private set; }
        public string DecodeScript { get; private set; }
        public string Error { get; private set; }
        private MethodInfo DeserializeFunc;
        private MethodInfo SerializeFunc;
        public DataParserConfig(IDataParser dataParser)
        {
            Name = dataParser.GetType().FullName;
            var lst = dataParser.GetStaticMethodNames();
            if (lst.Length < 3)
            {
                return;
            }
            ParseScript = Name + "." + lst[0];
            EncodeScript = Name + "." + lst[1];
            DecodeScript = Name + "." + lst[2];
            for (int i = 0; i < 3; i++)
            {
                var func = dataParser.GetType().GetMethod(lst[i], BindingFlags.Static | BindingFlags.Public);
                if (func == null)
                {
                    Error = "not exist static method " + Name + "." + lst[i];
                    return;
                }
                if (i == 0)
                {
                    DeserializeFunc = func;
                }
            }
            if (lst.Length > 3)
            {
                var tostring = dataParser.GetType().GetMethod(lst[3], BindingFlags.Static | BindingFlags.Public);
                if (tostring == null)
                {
                    Error = "not exist static method " + Name + "." + lst[3];
                    return;
                }
                if (tostring.GetParameters().Length != 2)
                {
                    Error = lst[3] + " need 2 parameter";
                    return;
                }
                if (tostring.ReturnParameter.ParameterType != typeof(string))
                {
                    Error = lst[3] + " return value type is string";
                    return;
                }
                this.SerializeFunc = tostring;
            }
        }
        public object Deserialize(string value)
        {
            return DeserializeFunc.Invoke(null, new object[] { value });
        }
        public string SerializeObject(object target, string userData)
        {
            if (SerializeFunc == null)
            {
                return "";
            }
            return SerializeFunc.Invoke(null, new object[] { target, userData }).ToString();
        }
    }
}